package com.ruoyi.project.system.service.impl

import com.ruoyi.common.constant.CacheConstants
import com.ruoyi.common.constant.UserConstants
import com.ruoyi.common.core.text.Convert.toBool
import com.ruoyi.common.core.text.Convert.toStr
import com.ruoyi.common.exception.ServiceException
import com.ruoyi.common.utils.*
import com.ruoyi.framework.redis.RedisCache
import com.ruoyi.project.system.domain.SysConfig
import com.ruoyi.project.system.mapper.SysConfigMapper
import com.ruoyi.project.system.service.ISysConfigService
import org.apache.commons.lang3.StringUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import javax.annotation.PostConstruct

/**
 * 参数配置 服务层实现
 *
 * @author ruoyi
 */
@Service
class SysConfigServiceImpl : ISysConfigService {
    @Autowired
    private val configMapper: SysConfigMapper? = null

    @Autowired
    private val redisCache: RedisCache? = null

    /**
     * 项目启动时，初始化参数到缓存
     */
    @PostConstruct
    fun init() {
        loadingConfigCache()
    }

    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    override fun selectConfigById(configId: Long?): SysConfig {
        val config = SysConfig()
        config.configId = configId
        return configMapper!!.selectConfig(config)!!
    }

    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */
    override fun selectConfigByKey(configKey: String): String {
        val configValue: String = toStr(redisCache!!.getCacheObject(getCacheKey(configKey)))!!
        if (com.ruoyi.common.utils.StringUtils.isNotEmpty(configValue)) {
            return configValue
        }
        val config = SysConfig()
        config.configKey = configKey
        val retConfig = configMapper!!.selectConfig(config)
        if (com.ruoyi.common.utils.StringUtils.isNotNull(retConfig)) {
            redisCache.setCacheObject(getCacheKey(configKey), retConfig?.configValue)
            return retConfig!!.configValue!!
        }
        return StringUtils.EMPTY
    }

    /**
     * 获取验证码开关
     *
     * @return true开启，false关闭
     */
    override fun selectCaptchaEnabled(): Boolean {
        val captchaEnabled = selectConfigByKey("sys.account.captchaEnabled")
        return if (com.ruoyi.common.utils.StringUtils.isEmpty(captchaEnabled)) {
            true
        } else toBool(captchaEnabled)!!
    }

    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    override fun selectConfigList(config: SysConfig?): List<SysConfig>? {
        return configMapper!!.selectConfigList(config)
    }

    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    override fun insertConfig(config: SysConfig): Int {
        val row = configMapper!!.insertConfig(config)
        if (row > 0) {
            redisCache!!.setCacheObject(getCacheKey(config.configKey!!), config.configValue)
        }
        return row
    }

    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    override fun updateConfig(config: SysConfig): Int {
        val row = configMapper!!.updateConfig(config)
        if (row > 0) {
            redisCache!!.setCacheObject(getCacheKey(config.configKey!!), config.configValue)
        }
        return row
    }

    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     */
    override fun deleteConfigByIds(configIds: Array<Long?>) {
        for (configId in configIds) {
            val config = selectConfigById(configId)
            if (StringUtils.equals(UserConstants.YES, config.configType)) {
                throw ServiceException(String.format("内置参数【%1\$s】不能删除 ", config.configKey))
            }
            configMapper!!.deleteConfigById(configId)
            redisCache!!.deleteObject(getCacheKey(config.configKey!!))
        }
    }

    /**
     * 加载参数缓存数据
     */
    override fun loadingConfigCache() {
        val configsList = configMapper!!.selectConfigList(SysConfig())
        for (config in configsList!!) {
            redisCache!!.setCacheObject(getCacheKey(config.configKey!!), config.configValue)
        }
    }

    /**
     * 清空参数缓存数据
     */
    override fun clearConfigCache() {
        val keys = redisCache!!.keys(CacheConstants.SYS_CONFIG_KEY + "*")
        redisCache.deleteObject(keys)
    }

    /**
     * 重置参数缓存数据
     */
    override fun resetConfigCache() {
        clearConfigCache()
        loadingConfigCache()
    }

    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    override fun checkConfigKeyUnique(config: SysConfig): String {
        val configId = if (com.ruoyi.common.utils.StringUtils.isNull(config.configId)) -1L else config.configId!!
        val info = configMapper!!.checkConfigKeyUnique(config.configKey)
        return if (com.ruoyi.common.utils.StringUtils.isNotNull(info) && info?.configId!!.toLong() != configId) {
            UserConstants.NOT_UNIQUE
        } else UserConstants.UNIQUE
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    private fun getCacheKey(configKey: String): String {
        return CacheConstants.SYS_CONFIG_KEY + configKey
    }
}
